#==================================================
#	Turn
#==================================================
#  转向
#==================================================
# @datetime: 2021-9-12 10:58:45
#==================================================
extends "Action.gd"


## 旋转结束
signal turn_finished


## 旋转速度
export var rotation_speed : float = 3.0
## 偏移的角度（这会决定贴图方向）（默认顶部朝向目标位置）
export (float, -180, 180) var offset_degress : float = 0.0 setget set_offset_degress


var _host : Node2D
var _is_starting : bool = false
var _turn_to_position : Vector2 = Vector2.ZERO


# 偏移的弧度
onready var _offset_rot : float = deg2rad(offset_degress)



#==================================================
#   Set/Get
#==================================================
#(override)
func is_enabled() -> bool:
	return (
		_is_starting 
		&& .is_enabled() 
	)

func set_offset_degress(value: float) -> void:
	offset_degress = value
	_offset_rot = deg2rad(offset_degress)



#==================================================
#   自定义方法
#==================================================
#(override)
func _init_data():
	register_to_function("TurnTo")
	_host = get_host()
	get_property().rotation_speed = rotation_speed


#(override)
## @pos  旋转到目标点
func control(pos: Vector2):
	_turn_to_position = pos
	_is_starting = true


func stop():
	_is_starting = false


#(override)
func _process_execute(delta):
	if is_enabled():
		turn_to(
			_host.global_position, 
			_turn_to_position, 
			delta
		)


##  转向到目标位置 
## @from  角色位置
## @to  目标位置
## @delta  帧速率
func turn_to(from: Vector2, to: Vector2, delta: float) -> void:
	# 自身到目标的方向
	var dir = to.direction_to(from)
	get_property().face_dir = dir
	
	# 弧度方向
	#（站立的时候，人物头部是朝向上面的，所以为 Vector2.UP）
	# 但这样造成旋转的值多了 PI/2，所以减去，加上用户设置的偏移的弧度
	var rot_dir = Vector2.UP.rotated(_host.global_rotation - PI/2 + _offset_rot)
	# [面向角度]与[自身当前旋转角度]的点积
	var dot = dir.dot(rot_dir)
	
	# 旋转速度
	var r_speed = get_property().rotation_speed * delta
	# 旋转的值
	var v = sign(dot) * r_speed
	
	if (
		# 点积大小超过 rotation_speed 则进行旋转
		# 防止速度过快时的抖动问题
		abs(dot) > r_speed
		
		# 自身面向角度 和 自身到目标点的角度 不是在自身的背面
		# 有时在背面的 dot 值也会为 0，防止在这个时候突然转向到后面
		# 下面这个 rot_dir 旋转了 -PI/2 （90度）是因为角度默认朝上方
		# 所以逆时针旋转 90度 以跟默认角度朝左方的角度相匹配
		|| abs(rot_dir.rotated(-PI/2).angle() - dir.angle()) > PI/2
	):
		_host.rotate(v)
	
	else:
		_host.global_rotation = dir.angle() - PI/2 - _offset_rot
		_is_starting = false
		
		emit_signal("turn_finished")
